package com.mofang.ticketing.common.core.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @BelongsProject: pms-group-digitization
 * @BelongsPackage: com.mofang.common.core.util
 * @Author: jc
 * @CreateTime: 2022-05-20  17:45
 * @Version: 1.0
 */
public class DateUtil {

    public static final String DATE_FORMAT = "yyyy-MM-dd";
    public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String TIME_FORMAT = "HH:mm:ss";

    /**
     * 10位格式
     */
    private static final String DATE_SHORT = "yyyy-MM-dd";

    /**
     * 月-日
     */
    private static final String DATE_MM_DD = "MM-dd";

    /**
     * Date转10位格式
     *
     * @param date
     * @return
     */
    public static String getStringByDateShort(Date date) {
        SimpleDateFormat sf = new SimpleDateFormat(DATE_SHORT);
        return sf.format(date);
    }

    /**
     * 10位格式转Date
     *
     * @param str
     * @return
     */
    public static Date getDateByStringShort(String str) throws ParseException {
        SimpleDateFormat sf = new SimpleDateFormat(DATE_SHORT);
        return sf.parse(str);
    }

    /**
     * 10位格式转Date
     *
     * @param date
     * @return
     */
    public static Date getDateShortByDate(Date date) {
        SimpleDateFormat sf = new SimpleDateFormat(DATE_SHORT);
        try {
            return sf.parse(sf.format(date));
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 转换MM-dd
     *
     * @param date
     * @return
     */
    public static String getStringByDateMMdd(Date date) {
        SimpleDateFormat sf = new SimpleDateFormat(DATE_MM_DD);
        return sf.format(date);
    }

    /**
     * 日期加减 日
     *
     * @param date 日期
     * @param days 加减 日
     * @return
     */
    public static Date getDayBefore(Date date, int days) {
        if (date == null) {
            return null;
        }
        if (days == 0) {
            return date;
        }
        Calendar curr = Calendar.getInstance();
        curr.setTime(date);
        curr.add(Calendar.DATE, days);
        return curr.getTime();
    }

    /**
     * 日期加减 周
     *
     * @param date 日期
     * @param week 加减 周
     * @return
     */
    public static Date getWeekBefore(Date date, int week) {
        if (date == null) {
            return null;
        }
        if (week == 0) {
            return date;
        }
        Calendar curr = Calendar.getInstance();
        curr.setTime(date);
        curr.add(Calendar.WEEK_OF_MONTH, week);
        return curr.getTime();
    }

    /**
     * 日期加减 月
     *
     * @param date  日期
     * @param month 加减 月
     * @return
     */
    public static Date getMonthBefore(Date date, int month) {
        if (date == null) {
            return null;
        }
        Calendar curr = Calendar.getInstance();
        curr.setTime(date);
        curr.add(Calendar.MONTH, month);
        return curr.getTime();
    }

    /**
     * 日期加减 年
     *
     * @param date  日期
     * @param years 加减 年
     * @return
     */
    public static Date getYearBefore(Date date, int years) {
        if (date == null) {
            return null;
        }
        Calendar curr = Calendar.getInstance();
        curr.setTime(date);
        curr.add(Calendar.YEAR, years);
        return curr.getTime();
    }

    /**
     * 两个日期之间的日期
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static List<Date> getBetweenDate(Date startDate, Date endDate) {
        Calendar currStart = Calendar.getInstance();
        currStart.setTime(startDate);

        List<Date> priceDates = new ArrayList<>();
        while (currStart.getTime().getTime() <= endDate.getTime()) {
            priceDates.add(currStart.getTime());

            currStart.add(Calendar.DATE, 1);
        }
        return priceDates;
    }

    /**
     * 两个日期之间的日期
     *
     * @param startTime
     * @param endTime
     * @return
     */
    public static List<Date> getBetweenDate(String startTime, String endTime) throws ParseException {
        Date startDate = getDateByStringShort(startTime);
        Date endDate = getDateByStringShort(endTime);
        return getBetweenDate(startDate, endDate);
    }

    /**
     * 获取周几 数字
     *
     * @param date
     * @return
     */
    public static int getWeekIntByDate(Date date) {
        String[] weekDays = {"7", "1", "2", "3", "4", "5", "6"};
        Calendar curr = Calendar.getInstance();
        curr.setTime(date);
        int week = curr.get(Calendar.DAY_OF_WEEK) - 1;
        return Integer.parseInt(weekDays[week]);
    }

    /**
     * 获取周几 字符串
     *
     * @param date
     * @return
     */
    public static String getWeekStrByDate(Date date) {
        String[] weekDays = {"日", "一", "二", "三", "四", "五", "六"};
        int week = getWeekIntByDate(date);
        if (week == 7) {
            week = 0;
        }
        return weekDays[week];
    }

    /**
     * 获取时分
     *
     * @param date
     * @return
     */
    public static String getHourMinute(Date date) {
        return cn.hutool.core.date.DateUtil.format(date, "HH:mm");
    }


    public static Date setHourMinute(Integer hour, Integer minute) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取当前日期的周一
     *
     * @param date
     * @return
     */
    public static Date getWeekMonday(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        // 获得当前日期是一个星期的第几天
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
        if (1 == dayWeek) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        // 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        // 获得当前日期是一个星期的第几天
        int day = cal.get(Calendar.DAY_OF_WEEK);
        // 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);
        return cal.getTime();
    }

    /**
     * 获取当前日期月的第一天
     *
     * @param date
     * @return
     */
    public static Date getFirstDayMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        return cal.getTime();
    }

    /**
     * 获取当前日期年的第一天
     *
     * @param date
     * @return
     */
    public static Date getFirstDayYear(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_YEAR, 1);
        return cal.getTime();
    }

    /**
     * 获取当前日期周
     *
     * @param date
     * @return
     */
    public static int getWeekByDate(Date date) {
        Calendar cal = Calendar.getInstance();
        // 设置一周的第一天为周一
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        cal.setTime(date);
        return cal.get(Calendar.WEEK_OF_YEAR);
    }

    /**
     * 获取当前日期月份
     *
     * @param date
     * @return
     */
    public static int getMonthByDate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取当前日期年份
     *
     * @param date
     * @return
     */
    public static int getYearByDate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.YEAR);
    }

    /**
     * 获取近七天日期
     */
    public static List<Date> getSevenDate() {
        Date nowDate = new Date();
        return getBetweenDate(getDayBefore(nowDate, -6), nowDate);
    }

    /**
     * 获取近七天日期
     */
    public static List<String> getSevenDateStr() {
        List<String> result = new ArrayList<>();
        Date nowDate = new Date();
        List<Date> betweenDate = getBetweenDate(getDayBefore(nowDate, -6), nowDate);
        for (Date date : betweenDate) {
            result.add(cn.hutool.core.date.DateUtil.formatDate(date));
        }
        return result;
    }

    /**
     * 获取指定日期，指定天数分组数据
     */
    public static Map<Integer, List<String>> getSevenDayWeekMap(Date startDate, Date endDate) {
        return getSevenDayWeekMap(startDate, endDate, 7);
    }

    /**
     * 获取指定日期，指定天数分组数据
     */
    public static Map<Integer, List<String>> getSevenDayWeekMap(Date startDate, Date endDate, Integer dayCount) {
        List<Date> monthDateList = getBetweenDate(startDate, endDate);
        int size = monthDateList.size();
        // 到当前日期共有多少周
        int diff = size / dayCount;
        int mou = size % dayCount;
        int weekCount = mou == 0 ? diff : diff + 1;
        Map<Integer, List<String>> map = new HashMap<>(weekCount);
        for (int i = 1; i <= weekCount; i++) {
            map.put(i, monthDateList.subList((i - 1) * dayCount, i <= diff ? i * dayCount : (i - 1) * dayCount + mou)
                    .stream().map(cn.hutool.core.date.DateUtil::formatDate).collect(Collectors.toList()));
        }
        return map;
    }

    /**
     * 获取指定时间当年  1月到日期当月月份集合
     */
    public static List<Integer> getMonthOfCurrYearList(Date date) {
        List<Integer> monthList = new ArrayList<>();
        int month = cn.hutool.core.date.DateUtil.month(date);
        for (int i = 0; i <= month; i++) {
            monthList.add(i);
        }
        return monthList;
    }

    public static void main(String[] args) {
        Date currDate = new Date();
        System.out.println(cn.hutool.core.date.DateUtil.beginOfMonth(currDate));
        Map<Integer, List<String>> sevenDayWeekMap = DateUtil.getSevenDayWeekMap(cn.hutool.core.date.DateUtil.beginOfMonth(currDate), currDate);
//        Map<Integer, List<String>> sevenDayWeekMap = com.mofang.ssa.common.core.util.DateUtil.getSevenDayWeekMap(cn.hutool.core.date.DateUtil.parseDate("2022-12-31"), currDate);
        System.out.println(sevenDayWeekMap);

        List<Integer> monthOfCurrYearList = DateUtil.getMonthOfCurrYearList(currDate);
        System.out.println(monthOfCurrYearList);
    }
}